<html>
  <head>
	  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>i5ting_ztree_toc:多线程（四）Atomic 原子类</title>
		<link href="toc/style/github-bf51422f4bb36427d391e4b75a1daa083c2d840e.css" media="all" rel="stylesheet" type="text/css"/>
		<link href="toc/style/github2-d731afd4f624c99a4b19ad69f3083cd6d02b81d5.css" media="all" rel="stylesheet" type="text/css"/>
		<link href="toc/css/zTreeStyle/zTreeStyle.css" media="all" rel="stylesheet" type="text/css"/>
	  <style>
		pre {
		    counter-reset: line-numbering;
		    border: solid 1px #d9d9d9;
		    border-radius: 0;
		    background: #fff;
		    padding: 0;
		    line-height: 23px;
		    margin-bottom: 30px;
		    white-space: pre;
		    overflow-x: auto;
		    word-break: inherit;
		    word-wrap: inherit;
		}

		pre a::before {
		  content: counter(line-numbering);
		  counter-increment: line-numbering;
		  padding-right: 1em; /* space after numbers */
		  width: 25px;
		  text-align: right;
		  opacity: 0.7;
		  display: inline-block;
		  color: #aaa;
		  background: #eee;
		  margin-right: 16px;
		  padding: 2px 10px;
		  font-size: 13px;
		  -webkit-touch-callout: none;
		  -webkit-user-select: none;
		  -khtml-user-select: none;
		  -moz-user-select: none;
		  -ms-user-select: none;
		  user-select: none;
		}

		pre a:first-of-type::before {
		  padding-top: 10px;
		}

		pre a:last-of-type::before {
		  padding-bottom: 10px;
		}

		pre a:only-of-type::before {
		  padding: 10px;
		}

		.highlight { background-color: #ffffcc } /* RIGHT */
		</style>
  </head>
  <body>
	  <div>
				<div style='width:25%;'>
						<ul id="tree" class="ztree" style='width:100%'>

						</ul>
				</div>
        <div id='readme' style='width:70%;margin-left:20%;'>
          	<article class='markdown-body'>
            	<h1 id="atomic-">Atomic 原子类</h1>
<h3 id="1-atomic-">1、Atomic 原子类介绍</h3>
<p>Atomic 翻译成中文是原子的意思，Atomic 是指一个操作是不可中断的。即使是在多个线程一起执行的时候，一个操作一旦开始，就不会被其他线程干扰。原子类说简单点就是具有原子/原子操作特征的类。</p>
<h3 id="2-juc-4-">2、JUC包中的4类原子类</h3>
<h4 id="-"><strong>基本类型</strong></h4>
<p>使用原子的方式更新基本类型</p>
<ul>
<li>AtomicInteger：整型原子类</li>
<li>AtomicLong：长整型原子类</li>
<li>AtomicBoolean ：布尔型原子类</li>
</ul>
<p>上面三个类提供的方法几乎相同，以 AtomicInteger 为例子：</p>
<h5 id="atomicinteger-"><strong>AtomicInteger 类常用方法</strong></h5>
<pre><code class="lang-java">public final int get() //获取当前的值
public final int getAndSet(int newValue)//获取当前的值，并设置新的值
public final int getAndIncrement()//获取当前的值，并自增
public final int getAndDecrement() //获取当前的值，并自减
public final int getAndAdd(int delta) //获取当前的值，并加上预期的值
boolean compareAndSet(int expect, int update) //如果输入的数值等于预期值，则以原子方式将该值设置为输入值（update）
public final void lazySet(int newValue)//最终设置为newValue,使用 lazySet 设置之后可能导致其他线程在之后的一小段时间内还是可以读到旧的值。
</code></pre>
<p>AtomicInteger 类主要利用 CAS (compare and swap) + volatile 和 native 方法来保证原子操作，从而避免 synchronized 的高开销，执行效率大为提升。</p>
<p>CAS的原理是拿期望的值和原本的一个值作比较，如果相同则更新成新的值。UnSafe 类的 objectFieldOffset() 方法是一个本地方法，这个方法是用来拿到“原来的值”的内存地址。另外 value 是一个volatile变量，在内存中可见，因此 JVM 可以保证任何时刻任何线程总能拿到该变量的最新值。</p>
<h4 id="-"><strong>数组类型</strong></h4>
<p>使用原子的方式更新数组里的某个元素</p>
<ul>
<li>AtomicIntegerArray：整型数组原子类</li>
<li>AtomicLongArray：长整型数组原子类</li>
<li>AtomicReferenceArray ：引用类型数组原子类</li>
</ul>
<p>上面三个类提供的方法几乎相同，以 AtomicIntegerArray 为例子介绍：</p>
<p><strong>AtomicIntegerArray 类常用方法</strong></p>
<pre><code class="lang-java">public final int get(int i) //获取 index=i 位置元素的值
public final int getAndSet(int i, int newValue)//返回 index=i 位置的当前的值，并将其设置为新值：newValue
public final int getAndIncrement(int i)//获取 index=i 位置元素的值，并让该位置的元素自增
public final int getAndDecrement(int i) //获取 index=i 位置元素的值，并让该位置的元素自减
public final int getAndAdd(int i, int delta) //获取 index=i 位置元素的值，并加上预期的值
boolean compareAndSet(int i, int expect, int update) //如果输入的数值等于预期值，则以原子方式将 index=i 位置的元素值设置为输入值（update）
public final void lazySet(int i, int newValue)//最终将index=i 位置的元素设置为newValue,使用 lazySet 设置之后可能导致其他线程在之后的一小段时间内还是可以读
</code></pre>
<h4 id="-"><strong>引用类型</strong></h4>
<ul>
<li>AtomicReference：引用类型原子类</li>
<li>AtomicMarkableReference：原子更新带有标记的引用类型。该类将 boolean 标记与引用关联起来，可以降低ABA问题发生的几率，不可避免。</li>
<li>AtomicStampedReference ：原子更新带有版本号的引用类型。该类将整数值与引用关联起来，可用于解决原子的更新数据和数据的版本号，可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。</li>
</ul>
<pre><code class="lang-java">AtomicReference&lt;Person&gt; ar = new AtomicReference&lt;Person&gt;();
Person person = new Person(&quot;SnailClimb&quot;, 22);
ar.set(person);
Person updatePerson = new Person(&quot;Daisy&quot;, 20);
ar.compareAndSet(person, updatePerson);

System.out.println(ar.get().getName());
System.out.println(ar.get().getAge());
</code></pre>
<h4 id="-"><strong>对象的属性修改类型</strong></h4>
<ul>
<li>AtomicIntegerFieldUpdater:原子更新整型字段的更新器</li>
<li>AtomicLongFieldUpdater：原子更新长整型字段的更新器</li>
<li>AtomicReferenceFieldUpdater：原子更新引用类型里的字段</li>
</ul>
<pre><code class="lang-java">AtomicIntegerFieldUpdater&lt;User&gt; a = AtomicIntegerFieldUpdater.newUpdater(User.class, &quot;age&quot;);
User user = new User(&quot;Java&quot;, 22);
System.out.println(a.getAndIncrement(user));// 22
System.out.println(a.get(user));// 23
</code></pre>

          	</article>
        </div>
		</div>
  </body>
</html>
<script type="text/javascript" src="toc/js/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="toc/js/jquery.ztree.all-3.5.min.js"></script>
<script type="text/javascript" src="toc/js/ztree_toc.js"></script>
<script type="text/javascript" src="toc_conf.js"></script>

<SCRIPT type="text/javascript" >
<!--
$(document).ready(function(){
    var css_conf = eval(markdown_panel_style);
    $('#readme').css(css_conf)
    
    var conf = eval(jquery_ztree_toc_opts);
		$('#tree').ztree_toc(conf);
});
//-->
</SCRIPT>